package utils

import (
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"strconv"
	"time"
)

const (
	TOKEN_NORMAL_CODE  = 200
	TOKEN_EXP_CODE     = 500
	TOKEN_INVALID_CODE = 300
)

/**
生成token
*/
func NewToken(key string, maps map[string]interface{}) string {
	// 签名方式
	token := jwt.New(jwt.SigningMethodHS256)
	claims := make(jwt.MapClaims)

	for key, value := range maps {
		claims[key] = value
	}
	token.Claims = claims
	tokenString, _ := token.SignedString([]byte(key))
	return tokenString
}

/**
解析token
*/
func ParseToken(tokenString string, key string) (interface{}, bool) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		return []byte(key), nil
	})
	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return claims, true
	} else {
		fmt.Println(err)
		return "", false
	}
}

/**
验证token
*/
func VerifyToken(tokenString, key string, expTime int64) (int, string) {
	claims, ok := ParseToken(tokenString, key)
	t := time.Now()
	code := TOKEN_NORMAL_CODE
	tokenState := ""
	if ok {
		oldT, _ := strconv.ParseInt(claims.(jwt.MapClaims)["exp"].(string), 10, 64)
		ct := t.UTC().UnixNano()
		c := ct - oldT
		if c > expTime {
			ok = false
			tokenState = "token过期"
			code = TOKEN_EXP_CODE
		} else {
			tokenState = "token正常"
			code = TOKEN_NORMAL_CODE
		}
	} else {
		tokenState = "token无效"
		code = TOKEN_INVALID_CODE
	}
	return code, tokenState
}
